package com.qs.rocketmq.bt.mq;

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;

/**
 * 测试：使用RocketMQ发送三种类型的消息：同步消息、异步消息和单向消息。其中前两种消息是可靠的，因为会有发送是否成功的应答。
 * @since 2022-07-10 17:47:40
 */
public class MqProducer {

    private static final DefaultMQProducer producer;

    static {
        // 实例化消息生产者Producer
        producer = new DefaultMQProducer(MqConstant.PRODUCER_GROUP_NAME);
        // 设置NameServer的地址
        producer.setNamesrvAddr(MqConstant.MQ_NAME_SRV_ADDR);
    }

    public static void main(String[] args) throws Exception {

        // 同步消息
        syncSend();

      /*  // 异步消息
        asyncSend();

        // 单向消息
        onewaySend();*/
    }


    /**
     * 测试同步发送消息
     * 适用场景：这种可靠性同步地发送方式使用的比较广泛，比如：重要的消息通知，短信通知。
     */
    public static void syncSend() throws Exception {
        // 启动Producer实例
        producer.start();

        byte[] msgContent = ("测试同步发送消息").getBytes(RemotingHelper.DEFAULT_CHARSET);
        Message msg = new Message(MqConstant.TEST_TOPIC, "TagA", msgContent);
        SendResult sendResult = producer.send(msg);
        System.out.println("发送结果：" + sendResult);

        // 如果不再发送消息，关闭Producer实例。
        producer.shutdown();
    }


    /**
     * 测试异步发送消息
     * 适用场景：异步消息通常用在对响应时间敏感的业务场景，即发送端不能容忍长时间地等待Broker的响应。
     */
    public static void asyncSend() throws Exception{
        producer.start();
        byte[] msgContent = ("测试异步发送消息").getBytes(RemotingHelper.DEFAULT_CHARSET);
        Message msg = new Message(MqConstant.TEST_TOPIC, "TagB", msgContent);
        producer.send(msg, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println("发送结果：" + sendResult);
            }

            @Override
            public void onException(Throwable e) {
                System.out.println("发送出现异常：" + e);
            }
        }, 3000);

        Thread.sleep(5000);
        producer.shutdown();
    }

    /**
     * 测试单向发送消息
     * 适用场景：这种方式主要用在不特别关心发送结果的场景，例如日志发送。
     */
    public static void onewaySend() throws Exception{
        producer.start();

        byte[] msgContent = ("测试oneway方式发送消息").getBytes(RemotingHelper.DEFAULT_CHARSET);
        Message msg = new Message(MqConstant.TEST_TOPIC, "TagC", msgContent);
        producer.sendOneway(msg);

        producer.shutdown();
    }
}